package com.yang.utils;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * @author 张恒阳
 *
 */
public class PojoVo extends TreeMap<String, Object> implements Serializable {

	private static final long serialVersionUID = 1L;
	// 初始化的值
	private final String NOT_PUT = "NOT_PUT";
	// 上一次添加的值
	private Object puts = NOT_PUT;
	// 是否添加成功
	private Boolean putflag = false;
	// 转化为pojo的MAP
	private Map<String, Object> data = null;
	// 存储pojo对象
	private Map<String, Object> pojos = new HashMap<>();
	// 存储pojo的字符串信息
	private Set<String> pojoSet = new HashSet<>();
	// 上一次初始化的数据信息
	private String oldStr = null;

	/**
	 * 获取转化为data的map
	 * 
	 * @return
	 */
	public Map<String, Object> getData() {
		initMap();
		return data;
	}

	// 初始化datamap
	private synchronized void initMap() {
		if (data != null && !this.isChange()) {
			return;
		}
		this.oldStr = this.toString();
		data = new TreeMap<>();
		// 讲 map_key => mapKey
		for (java.util.Map.Entry<String, Object> set : this.entrySet()) {
			String key = set.getKey();
			Object value = set.getValue();
			StringBuilder sb = new StringBuilder();
			if (key != null && key.length() > 1) {
				char[] cs = key.toCharArray();

				int index = -1;
				for (int i = 0; i < cs.length; i++) {
					if (cs[i] != '_') {
						if (index != i) {
							sb.append(cs[i]);
						} else {
							if (cs[i] >= 97 && cs[i] <= 122) {
								char temp = (char) (cs[i] - 32);
								sb.append(temp);
							}
						}
					} else {
						if (i > 1) {
							index = i + 1;
						}
					}
				}
			} else {
				sb.append(key);
			}
			data.put(sb.toString(), value);
		}

	}

	/**
	 * 获取转化为某一个实体类
	 * 
	 * @param name
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public <K> K getPojo(Class<K> name) {
		String beanName = name.getName();
		if (beanName == null || beanName.isEmpty()) {
			return null;
		}
		// 从内存中读取bean
		if (!pojoSet.add(beanName) && !this.isChange() && this.pojos.get(beanName) != null) {
			return (K) this.pojos.get(beanName);
		}
		// System.out.println("初始化pojo了....");
		K bean = null;
		try {
			bean = name.newInstance();
			this.initMap();
			BeanUtils.populate(bean, data);
		} catch (Exception e) {
			return null;
		}
		// 放入pojo缓存中
		pojos.put(beanName, bean);
		return bean;
	}

	/**
	 * 优化put方法
	 * 
	 * @see java.util.TreeMap#put(java.lang.Object, java.lang.Object)
	 */
	// @Override
	// public MyPojo put(String key, Object value) {
	// // TODO Auto-generated method stub
	//
	// Object put = super.put(key, value);
	// if (put != null) {
	// this.puts = put;
	// this.putflag = true;
	// } else {
	// this.puts = null;
	// this.putflag = false;
	// }
	// return this;
	// }
	/**
	 * 优化put方法
	 * 
	 * @see java.util.TreeMap#put(java.lang.Object, java.lang.Object)
	 */
	public PojoVo add(String key, Object value) {
		// TODO Auto-generated method stub
		if (key == null) {
			this.putflag = false;
			return this;
		}
		Object put = super.put(key, value);
		this.puts = put;
		if (put != null) {
			this.putflag = true;
		} else {
			this.putflag = false;
		}
		return this;
	}

	/**
	 * 上一次是否添加成功
	 * 
	 * @return
	 */
	public Boolean isPut() {
		return this.putflag;
	}

	/**
	 * 上一次添加的值,初始化为 NOT_PUT
	 * 
	 * @return
	 */
	public Object getPutData() {
		return this.puts;
	}

	/**
	 * 是否改变了
	 * 
	 * @return
	 */
	public Boolean isChange() {
		return !this.toString().equals(this.oldStr);
	}

	/**
	 * 获取对应data的映射关系
	 * 
	 * @return
	 */
	public Set<java.util.Map.Entry<String, Object>> getDataEntrySet() {
		this.initMap();
		return this.data.entrySet();
	}

	/**
	 * 获取元数据中的值
	 * 
	 * @param key
	 * @param name
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <E> E getValue(String key, Class<E> name) {
		if (StringUtils.isBlank(key) || name == null) {
			return null;
		}
		Object ob = this.get(key);
		return ob == null ? null : (E) ob;
	}

	/**
	 * 获取映射过的 map value
	 * 
	 * @param key
	 * @return
	 */
	public Object getDataValue(String key) {
		if (key == null) {
			return null;
		}
		this.initMap();
		return this.data.get(key);

	}

}
